import usePlayControl from '@/store/modules/playControl'
export default class Interval {
  constructor(callback, step = 512, viewNum = 1024, total = 32000, id) {
    this.id = id === undefined ? Math.random() : id
    this.start = 0
    this.callback = callback
    this.step = step
    this.viewNum = viewNum
    this.total = total
    this.isLoadedLast = false
    this.destroyed = false
    this.playControl = usePlayControl()
    this.once = false
    this.play()
  }
  play(once) {
    this.once = once
    this.timer && this.pause()
    this.timer = setInterval(() => {
      this.next()
    }, this.playControl.playbackRate)
  }
  pause() {
    clearInterval(this.timer)
    this.timer = null
  }
  next() {
    const num = this.start + this.step
    if (num >= this.total || num < 0) {
      this.start = 0
      this.callback(this.start)
      this.once && this.stop()
      return
    }
    if (num + this.viewNum >= this.total) {
      if (!this.isLoadedLast) {
        this.start = this.total - this.viewNum
        this.once && this.stop()
        this.isLoadedLast = true
      } else {
        this.start = 0
        this.isLoadedLast = false
      }
    } else {
      this.start = num
    }
    this.callback(this.start)
  }
  back() {
    this.start -= this.step
    if (this.start < 0) {
      this.start = 0
    }
    this.callback(this.start)
  }
  restart() {
    this.stop()
    this.play()
  }
  stop() {
    this.start = 0
    this.pause()
  }
  setParam(key, value) {
    this[key] = value
    this.restart()
  }
  setParams(params) {
    Object.keys(params).forEach(key => {
      this[key] = params[key]
    })
    this.restart()
  }
  destroy() {
    this.pause()
    this.playControl.del(this)
    Object.keys(this).forEach(key => {
      delete this[key]
    })
    this.destroyed = true
    Object.setPrototypeOf(this, null)
  }
  static create(callback, ...args) {
    const playControl = usePlayControl()
    const key = args[3]
    const interval = playControl.intervals.find(item => {
      if (item.id === key) {
        return item
      }
    })
    if (interval) {
      interval.callback = callback
      interval.play()
      return interval
    } else {
      const instance = new Interval(callback, ...args)
      playControl.add(instance)
      return instance
    }
  }
  static remove(instance) {
    if (!instance || instance.destroyed) {
      return
    }
    const playControl = usePlayControl()
    instance.destroy()
    const index = playControl.intervals.findIndex(interval => interval.destroyed)
    if (index > -1) {
      playControl.intervals.splice(index, 1)
    }
  }
}
